﻿using System;
using Xunit;

namespace Unity.String.Tests.Number
{
    public class MathExtendTest
    {
        [Fact]
        public void DivRemUnsignedIntTest()
        {
            uint funcResult = MathExtend.DivRem(5u, 2u, out uint argResult);
            Assert.Equal(2u, funcResult);
            Assert.Equal(1u, argResult);
        }
        
        [Fact]
        public void MethodsTestUnsignedLongTest()
        {
            ulong funcResult = MathExtend.DivRem(5ul, 2ul, out ulong argResult);
            Assert.Equal(2ul, funcResult);
            Assert.Equal(1ul, argResult);
        }
        
        [Fact]
        public void DivRemIntTest()
        {
            int funcResult = MathExtend.DivRem(5, 2, out int argResult);
            Assert.Equal(2, funcResult);
            Assert.Equal(1, argResult);
        }
        
        [Fact]
        public void DivRemLongTest()
        {
            long funcResult = MathExtend.DivRem(5L, 2L, out long argResult);
            Assert.Equal(2L, funcResult);
            Assert.Equal(1L, argResult);
        }
        
        [Fact]
        public void ClampByteTest()
        {
            Assert.Equal((byte)5, MathExtend.Clamp((byte)5, (byte)0, (byte)10));
            Assert.Equal((byte)5, MathExtend.Clamp((byte)0, (byte)5, (byte)10));
            Assert.Equal((byte)10, MathExtend.Clamp((byte)15, (byte)0, (byte)10));
        }
        
        [Fact]
        public void ClampSignedByteTest()
        {
            Assert.Equal((sbyte)5, MathExtend.Clamp((sbyte)5, (sbyte)0, (sbyte)10));
            Assert.Equal((sbyte)0, MathExtend.Clamp((sbyte)-5, (sbyte)0, (sbyte)10));
            Assert.Equal((sbyte)10, MathExtend.Clamp((sbyte)15, (sbyte)0, (sbyte)10));
        }
        
        [Fact]
        public void ClampDecimalTest()
        {
            const decimal parameter1 = 5;
            const decimal parameter2 = -5;
            const decimal parameter3 = 15;
            const decimal min = 0;
            const decimal max = 10;
            Assert.Equal(parameter1, MathExtend.Clamp(parameter1, min, max));
            Assert.Equal(min, MathExtend.Clamp(parameter2, min, max));
            Assert.Equal(max, MathExtend.Clamp(parameter3, min, max));
        }
        
        [Fact]
        public void ClampFloatTest()
        {
            Assert.Equal(5f, MathExtend.Clamp(5f, 0f, 10f));
            Assert.Equal(0f, MathExtend.Clamp(-5f, 0f, 10f));
            Assert.Equal(10f, MathExtend.Clamp(15f, 0f, 10f));
        }
        
        [Fact]
        public void ClampDoubleTest()
        {
            Assert.Equal(5d, MathExtend.Clamp(5d, 0d, 10d));
            Assert.Equal(0d, MathExtend.Clamp(-5d, 0d, 10d));
            Assert.Equal(10d, MathExtend.Clamp(15d, 0d, 10d));
        }
        
        [Fact]
        public void ClampShortTest()
        {
            Assert.Equal((short)5, MathExtend.Clamp((short)5, (short)0, (short)10));
            Assert.Equal((short)0, MathExtend.Clamp((short)-5, (short)0, (short)10));
            Assert.Equal((short)10, MathExtend.Clamp((short)15, (short)0, (short)10));
        }
        
        [Fact]
        public void ClampUnsignedShortTest()
        {
            Assert.Equal((ushort)5, MathExtend.Clamp((ushort)5, (ushort)0, (ushort)10));
            Assert.Equal((ushort)5, MathExtend.Clamp((ushort)0, (ushort)5, (ushort)10));
            Assert.Equal((ushort)10, MathExtend.Clamp((ushort)15, (ushort)0, (ushort)10));
        }
        
        [Fact]
        public void ClampIntTest()
        {
            Assert.Equal(5, MathExtend.Clamp(5, 0, 10));
            Assert.Equal(0, MathExtend.Clamp(-5, 0, 10));
            Assert.Equal(10, MathExtend.Clamp(15, 0, 10));
        }
        
        [Fact]
        public void ClampUnsignedIntTest()
        {
            Assert.Equal(5u, MathExtend.Clamp(5u, 0u, 10u));
            Assert.Equal(5u, MathExtend.Clamp(0u, 5u, 10u));
            Assert.Equal(10u, MathExtend.Clamp(15u, 0u, 10u));
        }
        
        [Fact]
        public void ClampLongTest()
        {
            Assert.Equal(5L, MathExtend.Clamp(5L, 0L, 10L));
            Assert.Equal(0L, MathExtend.Clamp(-5L, 0L, 10L));
            Assert.Equal(10L, MathExtend.Clamp(15L, 0L, 10L));
        }
        
        [Fact]
        public void ClampUnsignedLongTest()
        {
            Assert.Equal(5UL, MathExtend.Clamp(5UL, 0UL, 10UL));
            Assert.Equal(5UL, MathExtend.Clamp(0UL, 5UL, 10UL));
            Assert.Equal(10UL, MathExtend.Clamp(15UL, 0UL, 10UL));
        }
        
        [Fact]
        public void ClampMinMaxExceptionTest()
        {
            Assert.Throws<ArgumentException>(() => { MathExtend.Clamp((byte)0, (byte)10, (byte)0);});
            Assert.Throws<ArgumentException>(() => { MathExtend.Clamp((decimal)0, (decimal)10, (decimal)0);});
            Assert.Throws<ArgumentException>(() => { MathExtend.Clamp(0d, 10d, 0d);});
            Assert.Throws<ArgumentException>(() => { MathExtend.Clamp((short)0, (short)10, (short)0);});
            Assert.Throws<ArgumentException>(() => { MathExtend.Clamp(0, 10, 0);});
            Assert.Throws<ArgumentException>(() => { MathExtend.Clamp(0L, 10L,0);});
            Assert.Throws<ArgumentException>(() => { MathExtend.Clamp((sbyte)0, (sbyte)10, (sbyte)0);});
            Assert.Throws<ArgumentException>(() => { MathExtend.Clamp(0f, 10f, 0f);});
            Assert.Throws<ArgumentException>(() => { MathExtend.Clamp((ushort)0, (ushort)10, (ushort)0);});
            Assert.Throws<ArgumentException>(() => { MathExtend.Clamp(0u, 10u, 0u);});
            Assert.Throws<ArgumentException>(() => { MathExtend.Clamp(0ul, 10ul, 0ul);});
            
        }
        
    }
}